package com.niiwoo.civet.account.service.dubbo;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.dubbo.config.annotation.Service;
import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageInfo;
import com.niiwoo.civet.account.dao.entity.*;
import com.niiwoo.civet.account.dao.mapper.NiiwooBillMapperExt;
import com.niiwoo.civet.account.dto.bill.BillBase;
import com.niiwoo.civet.account.dto.bill.BillImgDTO;
import com.niiwoo.civet.account.dto.common.BillCodeDTO;
import com.niiwoo.civet.account.dto.common.BillTitleDTO;
import com.niiwoo.civet.account.dto.common.ProjectBillCategoriesDTO;
import com.niiwoo.civet.account.dto.request.*;
import com.niiwoo.civet.account.dto.response.*;
import com.niiwoo.civet.account.enums.*;
import com.niiwoo.civet.account.service.NiiwooBillDubboService;
import com.niiwoo.civet.account.service.local.AccountService;
import com.niiwoo.civet.account.service.local.bill.*;
import com.niiwoo.civet.account.service.local.withdraw.WithdrawOrderService;
import com.niiwoo.civet.base.enums.BorrowProjectTypeEnum;
import com.niiwoo.civet.base.utils.ProjectInfoUtil;
import com.niiwoo.civet.trade.dto.common.ProjectDTO;
import com.niiwoo.civet.trade.dto.response.creditor.CreditorSaleDetailResponseDTO;
import com.niiwoo.civet.trade.dto.response.intelligenceInvest.ProjectPackageResponseDTO;
import com.niiwoo.civet.trade.service.creditor.CreditorRightsDubboService;
import com.niiwoo.civet.trade.service.intelligenceInvest.IntelligenceInvestDubboService;
import com.niiwoo.civet.trade.service.project.ProjectDubboService;
import com.niiwoo.civet.user.dto.response.UserBasicInfoResponseDTO;
import com.niiwoo.civet.user.service.UserBasicInfoDubboService;
import com.niiwoo.tripod.base.component.PrivacyMasks;
import com.niiwoo.tripod.base.exception.DecryptException;
import com.niiwoo.tripod.base.properties.PrivacyMaskProperties;
import com.niiwoo.tripod.lanmao.enums.UserRoleEnum;
import com.niiwoo.tripod.provider.dto.response.PageResponseDTO;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.util.Assert;
import org.springframework.util.CollectionUtils;
import org.springframework.validation.BindException;
import org.springframework.validation.Errors;
import org.springframework.validation.FieldError;
import org.springframework.validation.Validator;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by Jaylin on 2017/11/10.
 */
@Slf4j
@Service(version = "1.0.0")
public class NiiwooBillDubboServiceImpl implements NiiwooBillDubboService {

    @Autowired
    private NiiwooBillMapperExt niiwooBillMapperExt;
    @Autowired
    private NiiwooBillService niiwooBillService;
    @Autowired
    private NiiwooBillPlateformService niiwooBillPlateformService;
    @Autowired
    private NiiwooBillGuaranteeService niiwooBillGuaranteeService;
    @Autowired
    private NiiwooBillFacade niiwooBillFacade;
    @Autowired
    private BillFacade billFacade;
    @Autowired
    private BillDateReleatedService billDateReleatedService;
    @Autowired
    private BillBaseService billBaseService;
    @Autowired
    private AccountService accountService;
    @Autowired
    private PrivacyMasks privacyMasks;
    @Autowired
    private WithdrawOrderService withdrawOrderService;
    @Autowired
    private Validator springValidator;


    @Reference(version = "1.0.0")
    private UserBasicInfoDubboService userBasicInfoDubboService;
    @Reference(version = "1.0.0")
    private ProjectDubboService projectDubboService;
    @Reference(version = "1.0.0")
    private IntelligenceInvestDubboService intelligenceInvestDubboService;
    @Reference(version = "1.0.0")
    private CreditorRightsDubboService creditorRightsDubboService;


    @Override
    public void addThirdBills(List<AddThirdBillRequestDTO> addThirdBillRequestDTOList) {
        log.info("addThirdBills request:{}", JSON.toJSONString(addThirdBillRequestDTOList));
        List<SaveAccountBillRequest> accountBillRequestList = new ArrayList<>();

        addThirdBillRequestDTOList.forEach(thirdBillRequestDTO -> {
            //账单
            SaveAccountBillRequest saveAccountBillRequest = new SaveAccountBillRequest();
            accountBillRequestList.add(saveAccountBillRequest);

            saveAccountBillRequest.setUserId(thirdBillRequestDTO.getUserId());
            saveAccountBillRequest.setAccountId(-1L);
            saveAccountBillRequest.setBillType(thirdBillRequestDTO.getBillType());
            saveAccountBillRequest.setAmount(thirdBillRequestDTO.getAmount());
            saveAccountBillRequest.setInoutType(thirdBillRequestDTO.getInoutType());
            saveAccountBillRequest.setBalanceAmount(BigDecimal.ZERO);
            saveAccountBillRequest.setChannelCode(thirdBillRequestDTO.getChannelCodeEnum());
            saveAccountBillRequest.setRequestNo(thirdBillRequestDTO.getRequestNo());
            saveAccountBillRequest.setProjectId(thirdBillRequestDTO.getProjectId());
            saveAccountBillRequest.setOrderId(0L);
            saveAccountBillRequest.setOrderType(OrderTypeEnum.NONE);
            saveAccountBillRequest.setStatus(BillStatusEnum.SUCCESS);
            saveAccountBillRequest.setRemark(thirdBillRequestDTO.getRemark());

            //账单明细
            List<SaveBillDetailRequest> saveBillDetailList = new ArrayList<>();
            saveAccountBillRequest.setSaveBillDetailList(saveBillDetailList);

            List<AddThirdBillRequestDTO.BillDetail> thirdBillDetailList = thirdBillRequestDTO.getBillDetailList();
            thirdBillDetailList.forEach(thirdBillDetail -> {
                SaveBillDetailRequest saveBillDetailRequest = new SaveBillDetailRequest();
                saveBillDetailRequest.setAmount(thirdBillDetail.getAmount());
                saveBillDetailRequest.setBillSecondSubjectEnum(thirdBillDetail.getBillSecondSubjectEnum());
                saveBillDetailRequest.setRelationUserId(thirdBillDetail.getRelationUserId());
                saveBillDetailRequest.setCurrentPeriod(thirdBillDetail.getCurrentPeriod());
                saveBillDetailList.add(saveBillDetailRequest);
            });
        });

        //保存
        niiwooBillFacade.saveAccountBillList(accountBillRequestList);
    }

    @Override
    public void handAddBillAndChangeBalance(HandAddBillAndChangeBalanceDTO handAddBillAndChangeBalanceDTO) {
        log.info("handAddBillAndChangeBalance request:{}", JSON.toJSONString(handAddBillAndChangeBalanceDTO));

        billFacade.handAddBillAndChangeBalance(handAddBillAndChangeBalanceDTO);
    }

    @Override
    public Long billIntelligenceInvestForApply(BillIntelligenceInvestForApplyRequestDTO request) {
        log.info("interface billIntelligenceInvestForApply start, request:{}", JSON.toJSONString(request));
        Errors errors = new BindException(request,"请求参数");
        springValidator.validate(request, errors);
        if(errors.hasErrors()){
            FieldError fieldError = errors.getFieldErrors().get(0);
            throw new IllegalArgumentException(fieldError.getField().concat(fieldError.getDefaultMessage()));
        }

        Long orderSuccessAccountingId = billFacade.billIntelligenceInvestForApply(request);
        log.info("interface billIntelligenceInvestForApply end, orderSuccessAccountingId:{}, request:{}", orderSuccessAccountingId, JSON.toJSONString(request));
        return orderSuccessAccountingId;
    }

    @Override
    public void billIntelligenceInvestCancel(String userId, String packageOrderId){
        log.info("interface billIntelligenceInvestCancel start, userId:{}, packageOrderId:{}", userId, packageOrderId);
        billFacade.billIntelligenceInvestCancel(userId, packageOrderId);
        log.info("interface billIntelligenceInvestCancel end, userId:{}, packageOrderId:{}", userId, packageOrderId);
    }

    @Override
    public List<NiiwooUserBillResponseDTO> listUserBills(BillQueryRequest billQueryRequest) {
        log.info("listUserBills request:{}", JSON.toJSONString(billQueryRequest));
        //查询
        List<NiiwooBill> niiwooBills = niiwooBillService.listNiiwooBills(billQueryRequest);

        //组装返回对象
        List<NiiwooUserBillResponseDTO> dtoList = new ArrayList<>();
        for (NiiwooBill niiwooBill : niiwooBills) {
            dtoList.add(this.transToUserBillReponseDTO(niiwooBill));
        }

        return dtoList;
    }

    @Override
    public BillsPageResponseDTO pageUserBills(BillQueryRequest billQueryRequest) {
        log.info("pageUserBills request:{}", JSON.toJSONString(billQueryRequest));
        BillsPageResponseDTO billsPageResponseDTO = new BillsPageResponseDTO();

        //分页查询
        PageInfo<NiiwooBill> pageInfo = niiwooBillService.pageNiiwooBills(billQueryRequest);
        //组装返回对象
        List<NiiwooUserBillResponseDTO> dtoList = new ArrayList<>();
        for (NiiwooBill niiwooBill : pageInfo.getList()) {
            dtoList.add(this.transToUserBillReponseDTO(niiwooBill));
        }

        List<UserBillsResponseDTO> dtos = listBillResponseDTOs(billQueryRequest, dtoList);

        billsPageResponseDTO.setTotalPage(pageInfo.getPages());
        billsPageResponseDTO.setTotalCount(Long.valueOf(pageInfo.getTotal()).intValue());
        billsPageResponseDTO.setItems(dtos);
        billsPageResponseDTO.setTotalDesc(indexTopTitle(billQueryRequest));

        return billsPageResponseDTO;
    }

    @Override
    public PageResponseDTO<NiiwooBillRespDTO> queryUserBills(BillQueryRequest billQueryRequest) {
        PageResponseDTO<NiiwooBillRespDTO> billsPageResponseDTO = new PageResponseDTO<>();

        //分页查询
        PageInfo<NiiwooBill> pageInfo = niiwooBillService.pageNiiwooBills(billQueryRequest);
        //组装返回对象
        List<NiiwooBillRespDTO> dtoList = new ArrayList<>();
        for (NiiwooBill niiwooBill : pageInfo.getList()) {
            NiiwooBillRespDTO dto = new NiiwooBillRespDTO();
            BeanUtils.copyProperties(niiwooBill, dto);
            dtoList.add(dto);
        }

        billsPageResponseDTO.setTotalPage(pageInfo.getPages());
        billsPageResponseDTO.setTotalCount(Long.valueOf(pageInfo.getTotal()).intValue());
        billsPageResponseDTO.setItems(dtoList);
        return billsPageResponseDTO;
    }


    @Override
    public PageResponseDTO<NiiwooUserProjectBillReponseDTO> pageUserBillsGroupByPackage(BillQueryRequest billQueryRequest) {
        log.info("pageUserBillsGroupByProject request:{}", JSON.toJSONString(billQueryRequest));
        PageResponseDTO<NiiwooUserProjectBillReponseDTO> pageResponse = new PageResponseDTO<>();

//        List<String> firstCodeS = new ArrayList<>();
//        if (EntranceTypeEnum.BORROW_BILL.getCode().equals(billQueryRequest.getEntranceTypeEnum().getCode())) {
//            firstCodeS.add(BillFirstSubjectEnum.USER_BORROW_INCOME.getCode());
//            firstCodeS.add(BillFirstSubjectEnum.USER_REPAYMENT.getCode());
//        } else if (EntranceTypeEnum.INVEST_BILL.getCode().equals(billQueryRequest.getEntranceTypeEnum().getCode())) {
//            firstCodeS.add(BillFirstSubjectEnum.USER_INVEST.getCode());
//            firstCodeS.add(BillFirstSubjectEnum.USER_INVEST_REPAYMENT.getCode());
//        }
//        billQueryRequest.setFirstCodeS(firstCodeS);

        //分页查询项目的最新账单ID
        PageInfo<Long> billIdPageInfo = niiwooBillService.listLatestBillIdGroupByPackage(billQueryRequest.getUserId(), billQueryRequest.getPageNumber(), billQueryRequest.getPageSize(), billQueryRequest.getFirstCodeS());
        if (!CollectionUtils.isEmpty(billIdPageInfo.getList())) {
            //根据账单ID查询账单
            NiiwooBillExample niiwooBillExample = new NiiwooBillExample();
            NiiwooBillExample.Criteria criteria = niiwooBillExample.createCriteria();
            niiwooBillExample.setOrderByClause("bill_id desc");
            criteria.andUserIdEqualTo(billQueryRequest.getUserId());
            criteria.andBillIdIn(billIdPageInfo.getList());
            List<NiiwooBill> billList = niiwooBillMapperExt.selectByExample(niiwooBillExample);

            List<NiiwooUserProjectBillReponseDTO> dtoList = new ArrayList<>();
            for (NiiwooBill bill : billList) {
                //查询标的最近的一条账单
                NiiwooUserProjectBillReponseDTO niiwooUserProjectBillReponseDTO = new NiiwooUserProjectBillReponseDTO();
                niiwooUserProjectBillReponseDTO.setBillId(bill.getBillId());
                niiwooUserProjectBillReponseDTO.setOrderId(bill.getOrderId());
                if(Objects.nonNull(bill.getProjectId()) && bill.getProjectId().equals(bill.getProjectPackageId())){
                    niiwooUserProjectBillReponseDTO.setTitle(bill.getProjectTitle());
                }else {
                    if(Objects.nonNull(bill.getProjectPackageId())){
                        ProjectPackageResponseDTO projectPackageResponseDTO = this.queryProjectPackageInfo(bill.getProjectPackageId());
                        if(Objects.nonNull(projectPackageResponseDTO))
                            niiwooUserProjectBillReponseDTO.setTitle(projectPackageResponseDTO.getTitle());
                    }
                }
                niiwooUserProjectBillReponseDTO.setCreateTime(bill.getCreateTime());
                niiwooUserProjectBillReponseDTO.setProjectPackageId(bill.getProjectPackageId());
                BigDecimal totalBonusAmount = new BigDecimal(0);
                List<BillCodeDTO> billCodeDTOList = new ArrayList<>();
                List<ProjectBillCategoriesDTO> classifyDTOList = niiwooBillMapperExt.listCategoriesStatis(billQueryRequest.getUserId(), bill.getProjectPackageId());
                for (ProjectBillCategoriesDTO projectBillCategoriesDTO : classifyDTOList) {
                    if (BillFirstSubjectEnum.containBounsCode().contains(projectBillCategoriesDTO.getFirstSortCode())) {
                        totalBonusAmount = totalBonusAmount.add(projectBillCategoriesDTO.getAmount());
                    } else {
                        BillCodeDTO billCodeDTO = new BillCodeDTO();
                        if(projectBillCategoriesDTO.getInoutType() == 1){
                            billCodeDTO.setAmount(projectBillCategoriesDTO.getAmount());
                        }else {
                            billCodeDTO.setAmount(projectBillCategoriesDTO.getAmount().negate());
                        }

                        BillFirstSubjectEnum firstSubjectEnum = BillFirstSubjectEnum.getEnumByCode(projectBillCategoriesDTO.getFirstSortCode());
                        if (Objects.nonNull(firstSubjectEnum)) {
                            billCodeDTO.setCodeDesc(firstSubjectEnum.getTitle());
                        } else {
                            billCodeDTO.setCodeDesc("");
                        }
                        billCodeDTOList.add(billCodeDTO);
                    }
                }

                if (BigDecimal.ZERO.compareTo(totalBonusAmount) != 0) {
                    BillCodeDTO billCodeDTO = new BillCodeDTO();
                    billCodeDTO.setAmount(totalBonusAmount);
                    billCodeDTO.setCodeDesc("平台奖励");
                    billCodeDTOList.add(billCodeDTO);
                }

                //借款人显示借款人头像,投资人显示借款人头像(如果投资人投的机构标,则显示机构头像),查询不到显示默认头像
                BillImgDTO imgDTO = this.returnImage(bill);
                niiwooUserProjectBillReponseDTO.setBillImgSrc(imgDTO.getImgSrc());
                niiwooUserProjectBillReponseDTO.setAccountType(imgDTO.getAccountType());
//                if(Objects.nonNull(bill.getRelationAccountId()) && bill.getRelationAccountId() != -1) {
//                    AccountBase accountBase = accountService.loadAccountById(bill.getRelationAccountId());
//                    niiwooUserProjectBillReponseDTO.setAccountType(accountBase.getAccountType());
//                }
                niiwooUserProjectBillReponseDTO.setAmountTotalDetails(billCodeDTOList);

                dtoList.add(niiwooUserProjectBillReponseDTO);
            }

            pageResponse.setItems(dtoList);
        }

        pageResponse.setTotalCount(Long.valueOf(billIdPageInfo.getTotal()).intValue());
        pageResponse.setTotalPage(billIdPageInfo.getPages());
        return pageResponse;
    }

    private BillImgDTO returnImage(NiiwooBill bill) {
        BillImgDTO imgDTO = new BillImgDTO();

        if(!bill.getProjectPackageId().equals(bill.getProjectId())){
            //智能投写死头像地址
            log.info("bill image:智能投写死头像地址");
            imgDTO.setImgSrc("https://image.niiwoo.com/activity-manage/20181129/37ef3747-9e92-432e-8d60-b68b662f047b.png");
            imgDTO.setAccountType(AccountTypeEnum.PERSONAL.getValue());//随便写一个
            return imgDTO;
        }

        Long projectId = bill.getProjectId();
        if(BorrowProjectTypeEnum.TRANSFER_OF_CREDIT.getValue().equals(bill.getProjectType())){
            //查询债转标的底层标的
            log.info("bill image:债转标:{}",projectId);

            CreditorSaleDetailResponseDTO creditorSaleDetail = creditorRightsDubboService.getCreditorSaleDetail(Long.valueOf(bill.getProjectId()), null);
            if(Objects.nonNull(creditorSaleDetail)){
                projectId = creditorSaleDetail.getProjectId();
                log.info("bill image:债转标的底层标:{}",projectId);
            }
        }

        if (Objects.nonNull(projectId)) {
            ProjectDTO projectDTO = projectDubboService.selectProjectById(projectId);
            if(Objects.nonNull(projectDTO)) {
                UserBasicInfoResponseDTO userBasicInfoResponseDTO = userBasicInfoDubboService.selectUserBaseInfo(projectDTO.getBorrowUserId());
                log.info("bill image:userBasicInfoResponseDTO:{}",JSON.toJSONString(userBasicInfoResponseDTO));
                AccountBase accountBase = accountService.loadAccountById(projectDTO.getBorrowAccountId());

                imgDTO.setImgSrc(userBasicInfoResponseDTO == null ? "" : userBasicInfoResponseDTO.getHeadImage());
                imgDTO.setAccountType(accountBase.getAccountType());
            }
        }
        log.info("bill image:imgDTO:{}",imgDTO);
        return imgDTO;
    }

    @Override
    public List<NiiwooBillProjectDetailReponseDTO> queryProjectBillDetail(NiiwooBillProjectDetailRequestDTO requestDTO) {
        log.info("queryProjectBillDetail request:{}", JSON.toJSONString(requestDTO));
        List<NiiwooBillProjectDetailReponseDTO> dtoList = new ArrayList<>();

        BillQueryRequest billQueryRequest = new BillQueryRequest();
        billQueryRequest.setUserId(requestDTO.getUserId());
        billQueryRequest.setProjectPackageId(requestDTO.getProjectId());
        List<NiiwooBill> niiwooBillList = niiwooBillService.listNiiwooBills(billQueryRequest);

        for (NiiwooBill niiwooBill : niiwooBillList) {
            NiiwooBillProjectDetailReponseDTO niiwooBillProjectDetailReponseDTO = new NiiwooBillProjectDetailReponseDTO();
            niiwooBillProjectDetailReponseDTO.setBillId(niiwooBill.getBillId());
            niiwooBillProjectDetailReponseDTO.setOrderId(niiwooBill.getOrderId());
            if(InoutTypeEnum.IN_TYPE.getType().equals(niiwooBill.getInoutType())){
                niiwooBillProjectDetailReponseDTO.setAmount(niiwooBill.getAmount());
            }else {
                niiwooBillProjectDetailReponseDTO.setAmount(niiwooBill.getAmount().negate());
            }
            niiwooBillProjectDetailReponseDTO.setCreateTime(niiwooBill.getCreateTime());
            niiwooBillProjectDetailReponseDTO.setStatus(niiwooBill.getStatus());
            niiwooBillProjectDetailReponseDTO.setTitle(BillSecondSubjectEnum.getEnumByCode(niiwooBill.getSecondSortCode()).getTitle());
            dtoList.add(niiwooBillProjectDetailReponseDTO);
        }

        return dtoList;
    }

    @Override
    public NiiwooBillDetailReponseDTO getUserBillDetail(String userId, Long billId) {
        Assert.hasLength(userId, "userId不能为空");
        Assert.notNull(billId, "billId不能为空");

        BillQueryRequest request = new BillQueryRequest();
        request.setUserId(userId);
        request.setBillUserType(BillUserTypeEnum.GENERAL);
        request.setBillId(billId);
        List<NiiwooBill> niiwooBills = niiwooBillService.listNiiwooBills(request);
        if (CollectionUtils.isEmpty(niiwooBills)) {
            return null;
        }

        List<BillDetailReponseDTO> detailDTOs = new ArrayList<>();
        NiiwooBill niiwooBill = niiwooBills.get(0);
        String serialNumber = String.valueOf(niiwooBill.getBillId());
        BillSecondSubjectEnum niiwooUserBillEnum = BillSecondSubjectEnum.getEnumByCode(niiwooBill.getSecondSortCode());

        List<String> list = BillSecondSubjectEnum.listCurrentPeriodEnum();
        NiiwooBillDetailReponseDTO niiwooBillDetailReponseDTO = new NiiwooBillDetailReponseDTO();

        niiwooBillDetailReponseDTO.setOrderId(niiwooBill.getOrderId());
        niiwooBillDetailReponseDTO.setBankName(niiwooBill.getBankName());
        niiwooBillDetailReponseDTO.setBankAccountNo(niiwooBill.getBankAccountNo());
        niiwooBillDetailReponseDTO.setAmount(niiwooBill.getAmount());
        niiwooBillDetailReponseDTO.setInoutType(niiwooBill.getInoutType());
        niiwooBillDetailReponseDTO.setProjectId(niiwooBill.getProjectId());
        niiwooBillDetailReponseDTO.setProjectPackageId(niiwooBill.getProjectPackageId());

        String billType = niiwooUserBillEnum.getTitle();
        if (list.contains(niiwooBill.getFirstSortCode()) && Objects.nonNull(niiwooBill.getCurrentPeriod())) {
            billType = billType + "(第" + niiwooBill.getCurrentPeriod() + "/" + niiwooBill.getTotalPeriods() + "期)";
        }

        String status = "";
        if (BillStatusEnum.SUCCESS.getValue() == niiwooBill.getStatus()) status = BillStatusEnum.SUCCESS.getDesc();
        else if (BillStatusEnum.HANDLING.getValue() == niiwooBill.getStatus())
            status = BillStatusEnum.HANDLING.getDesc();
        else if (BillStatusEnum.CLOSE.getValue() == niiwooBill.getStatus()) status = BillStatusEnum.CLOSE.getDesc();

        detailDTOs.add(new BillDetailReponseDTO("交易类型", billType));
        BillDetailIndexEnum indexEnum = BillDetailIndexEnum.getTxDescByFirstCode(niiwooBill.getFirstSortCode());
        if (Objects.nonNull(indexEnum)) {
            if (StringUtils.isNotEmpty(indexEnum.getTxDesc())) {
                String desc = niiwooUserBillEnum.getCodeName();
                if (BillSecondSubjectEnum.USER_WITHDRAW_SERVICE_FEE.getCode().equals(niiwooBill.getSecondSortCode())) {
                    WithdrawOrder withdrawOrder = withdrawOrderService.loadWithdrawOrderById(Long.parseLong(niiwooBill.getOrderId()));
                    if (Objects.nonNull(withdrawOrder.getPrizeId())) {
                        BigDecimal subFee = withdrawOrder.getFee().subtract(withdrawOrder.getRealFee());
                        desc = "提现应付手续费" + withdrawOrder.getFee() + ",提现代金券抵扣" + subFee;
                    }
                }
                detailDTOs.add(new BillDetailReponseDTO(indexEnum.getTxDesc(), desc));
            }
            //资金来源、发放来源、还款类型等
            if (StringUtils.isNotEmpty(indexEnum.getBackCause()) && StringUtils.isNotEmpty(niiwooBill.getRemark2())) {
                detailDTOs.add(new BillDetailReponseDTO(indexEnum.getBackCause(), niiwooBill.getRemark2()));
            }
        }

        if (BillFirstSubjectEnum.USER_TRANSFER_IN.getCode().equals(niiwooBill.getFirstSortCode()) || BillFirstSubjectEnum.USER_TRANSFER_OUT.getCode().equals(niiwooBill.getFirstSortCode())) {
            AccountBase accountBaseOne = accountService.loadAccountById(niiwooBill.getAccountId());
            AccountBase accountBaseTwo = accountService.loadAccountById(niiwooBill.getRelationAccountId());

            if(Objects.nonNull(niiwooBill.getAccountId()) && niiwooBill.getAccountId() != -1) {
                if (UserRoleEnum.BORROWERS.getValue().equals(accountBaseOne.getAccountRole())) {
                    if (InoutTypeEnum.IN_TYPE.getType().equals(niiwooBill.getInoutType())) {
                        detailDTOs.add(new BillDetailReponseDTO("收入账户", "借款账户"));
                    } else if (InoutTypeEnum.OUT_TYPE.getType().equals(niiwooBill.getInoutType())) {
                        detailDTOs.add(new BillDetailReponseDTO("支出账户", "借款账户"));
                    }
                } else if (UserRoleEnum.INVESTOR.getValue().equals(accountBaseOne.getAccountRole())) {
                    if (InoutTypeEnum.IN_TYPE.getType().equals(niiwooBill.getInoutType())) {
                        detailDTOs.add(new BillDetailReponseDTO("收入账户", "投资账户"));
                    } else if (InoutTypeEnum.OUT_TYPE.getType().equals(niiwooBill.getInoutType())) {
                        detailDTOs.add(new BillDetailReponseDTO("支出账户", "投资账户"));
                    }
                }
            }

            if(Objects.nonNull(niiwooBill.getRelationAccountId()) && niiwooBill.getRelationAccountId() != -1) {
                if (UserRoleEnum.INVESTOR.getValue().equals(accountBaseTwo.getAccountRole())) {
                    if (InoutTypeEnum.IN_TYPE.getType().equals(niiwooBill.getInoutType())) {
                        detailDTOs.add(new BillDetailReponseDTO("支出账户", "投资账户"));
                    } else if (InoutTypeEnum.OUT_TYPE.getType().equals(niiwooBill.getInoutType())) {
                        detailDTOs.add(new BillDetailReponseDTO("收入账户", "投资账户"));
                    }
                } else if (UserRoleEnum.BORROWERS.getValue().equals(accountBaseTwo.getAccountRole())) {
                    if (InoutTypeEnum.IN_TYPE.getType().equals(niiwooBill.getInoutType())) {
                        detailDTOs.add(new BillDetailReponseDTO("支出账户", "借款账户"));
                    } else if (InoutTypeEnum.OUT_TYPE.getType().equals(niiwooBill.getInoutType())) {
                        detailDTOs.add(new BillDetailReponseDTO("收入账户", "借款账户"));
                    }
                }
            }
        }

        if (niiwooBill.getBackTime() != null) {
            detailDTOs.add(new BillDetailReponseDTO(indexEnum.getBackDate(), FastDateFormat.getInstance("yyyy-MM-dd HH:mm").format(niiwooBill.getBackTime())));
        }
        detailDTOs.add(new BillDetailReponseDTO("交易时间", FastDateFormat.getInstance("yyyy-MM-dd HH:mm").format(niiwooBill.getCreateTime())));
        detailDTOs.add(new BillDetailReponseDTO("交易流水号", serialNumber));
        detailDTOs.add(new BillDetailReponseDTO("交易状态", status));

        BillTitleDTO titleDTO = getDetailTitle(niiwooBill, serialNumber);

        niiwooBillDetailReponseDTO.setDetailDTOs(detailDTOs);
        niiwooBillDetailReponseDTO.setTitle(titleDTO.getTitle());
        niiwooBillDetailReponseDTO.setTitleDown(titleDTO.getTitleDown());
        niiwooBillDetailReponseDTO.setNeedJump(titleDTO.getNeedJump());
        niiwooBillDetailReponseDTO.setJumpType(titleDTO.getJumpType());
        niiwooBillDetailReponseDTO.setJumpTypeId(titleDTO.getJumpTypeId());

        return niiwooBillDetailReponseDTO;
    }

    @Override
    public MonthBillResponseDTO queryMonthBillDetailByMonth(MonthBillRequestDTO requestDTO) {



//        requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_INVEST_REPAYMENT_INTEREST.getCode());
        //利息收益
//        MonthBillCountResponseDTO interestIncome = niiwooBillService.getMonthBillSum(requestDTO);
//
//        requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_GUARANTEE_INCOME.getCode());
//        //担保收益
//        MonthBillCountResponseDTO guaranteeIncome = niiwooBillService.getMonthBillSum(requestDTO);
//
//        requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_GUARANTEE_INCOME_FEE.getCode());
//        //尽调收益
//        MonthBillCountResponseDTO reserch = niiwooBillService.getMonthBillSum(requestDTO);
//
//        requestDTO.setFirstSortCode(BillFirstSubjectEnum.USER_PLATFORM_GIVEN.getCode());
//        //平台奖励
//        MonthBillCountResponseDTO platformGiven = niiwooBillService.getMonthBillSumByUserIdAndMonthAndFirstSortCode(requestDTO);
//
//        //投资费用
//        MonthBillCountResponseDTO investServiceFee = niiwooBillService.getMonthBillSum(requestDTO);
//
//        requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_BORROW_GUARANTEE_FEE.getCode());
//        //担保费用
//        MonthBillCountResponseDTO guaranteeFee = niiwooBillService.getMonthBillSum(requestDTO);
//
//        requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_REPAYMENT_MANAGER_FEE.getCode());
//        //借款费用
//        MonthBillCountResponseDTO borrowServiceFee = niiwooBillService.getMonthBillSum(requestDTO);
//
//        requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_WITHDRAW_SERVICE_FEE.getCode());
//        //提现手续费
//        MonthBillCountResponseDTO withdrawServiceFee = niiwooBillService.getMonthBillSum(requestDTO);
//
//        requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_INVEST.getCode());
//        //投资
//        MonthBillCountResponseDTO investAmount = niiwooBillService.getMonthBillSum(requestDTO);
//
//        requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_INVEST_REPAYMENT_CORPUS.getCode());
//        //投资回款
//        MonthBillCountResponseDTO investReceive = niiwooBillService.getMonthBillSum(requestDTO);
//
//        requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_INVEST_REPAYMENT_CORPUS.getCode());
//        //平台发放
//        MonthBillCountResponseDTO platformSend = niiwooBillMapperExt.queryMonthBillPlatformSend(requestDTO.getMonth(), requestDTO.getUserId());
//
//        requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_BORROW_INCOME_AMOUNT.getCode());
//        //借款
//        MonthBillCountResponseDTO borrow = niiwooBillService.getMonthBillSum(requestDTO);
//
//        MonthBillResponseDTO monthBillDTO = new MonthBillResponseDTO();
//        monthBillDTO.setInterestIncome(interestIncome == null ? new BigDecimal("0.00") : interestIncome.getMonthIncome());
//        monthBillDTO.setGuaranteeIncome(guaranteeIncome == null ? new BigDecimal("0.00") : guaranteeIncome.getMonthIncome());
//        monthBillDTO.setResearch(reserch == null ? new BigDecimal("0.00") : reserch.getMonthIncome());
//        monthBillDTO.setPlatformReward(platformGiven == null ? new BigDecimal("0.00") : platformGiven.getMonthIncome());
//        monthBillDTO.setInvestServiceFee(investServiceFee == null ? new BigDecimal("0.00") : investServiceFee.getMonthIncome());
//        monthBillDTO.setGuaranteeFee(guaranteeFee == null ? new BigDecimal("0.00") : guaranteeFee.getMonthIncome());
//        monthBillDTO.setBorrowServiceFee(borrowServiceFee == null ? new BigDecimal("0.00") : borrowServiceFee.getMonthIncome());
//        monthBillDTO.setWithdrawServiceFee(withdrawServiceFee == null ? new BigDecimal("0.00") : withdrawServiceFee.getMonthIncome());
//        monthBillDTO.setInvestAmount(investAmount == null ? new BigDecimal("0.00") : investAmount.getMonthIncome());
//        monthBillDTO.setInvestReceive(investReceive == null ? new BigDecimal("0.00") : investReceive.getMonthIncome());
//        monthBillDTO.setPlatformSend(platformSend == null ? new BigDecimal("0.00") : platformSend.getMonthIncome());
//        monthBillDTO.setBorrowAmount(borrow == null ? new BigDecimal("0.00") : borrow.getMonthIncome());

        return null;
    }

    @Override
    public List<MonthBillCountResponseDTO> listMonthBill(String userId) {
        List<MonthBillCountResponseDTO> monthBillCountDTOList = niiwooBillService.listMonthBillIncomeByUserId(userId);
        return monthBillCountDTOList;
    }


    /********************************=========平台========****************************/
    @Override
    public PageResponseDTO<NiiwooPlatformBillReponseDTO> pagePlatformBills(PlatformBillQueryRequest billQueryRequest) {
        PageResponseDTO<NiiwooPlatformBillReponseDTO> pageResponse = new PageResponseDTO<>();

        //统计总数量
        Long totalCount = niiwooBillPlateformService.countPlatformBills(billQueryRequest);
        if (totalCount > billQueryRequest.getOffset()) {
            //分页查询
            List<NiiwooBillPlatform> niiwooBillPlatforms = niiwooBillPlateformService.pagePlatformBills(billQueryRequest);

            //组装返回对象
            List<NiiwooPlatformBillReponseDTO> dtoList = new ArrayList<>();
            for (NiiwooBillPlatform niiwooBillPlatform : niiwooBillPlatforms) {
                dtoList.add(this.transToPlatformBillReponseDTO(niiwooBillPlatform));
            }


            pageResponse.setTotalCount(totalCount.intValue());
            pageResponse.setItems(dtoList);
        }

        return pageResponse;
    }

    /*************************============担保分页==========********************************/

    @Override
    public PageResponseDTO<NiiwooGuaranteeBillReponseDTO> pageGuaranteeBills(GuaranteeBillQueryRequest billQueryRequest) {
        PageResponseDTO<NiiwooGuaranteeBillReponseDTO> pageResponseDTO = new PageResponseDTO<>();
        Long totalCount = niiwooBillGuaranteeService.countPlatformBills(billQueryRequest);
        if (totalCount > billQueryRequest.getOffset()) {
            List<NiiwooBillGuarantee> niiwooBillGuarantees = niiwooBillGuaranteeService.pageGuaranteeBills(billQueryRequest);

            List<NiiwooGuaranteeBillReponseDTO> dtoList = new ArrayList<>();
            for (NiiwooBillGuarantee niiwooBillGuarantee : niiwooBillGuarantees) {
                dtoList.add(this.transToGuaranteeBillResponseDTO(niiwooBillGuarantee));
            }

            pageResponseDTO.setTotalCount(totalCount.intValue());
            pageResponseDTO.setItems(dtoList);
        }

        return pageResponseDTO;
    }

    /*************************============担保不分页==========********************************/
    @Override
    public List<NiiwooGuaranteeBillReponseDTO> listGuaranteeBills(GuaranteeBillQueryRequest billQueryRequest) {
        List<NiiwooGuaranteeBillReponseDTO> result = new ArrayList<>();
        Long totalCount = niiwooBillGuaranteeService.countPlatformBills(billQueryRequest);
        if (totalCount > 0) {
            List<NiiwooBillGuarantee> niiwooBillGuarantees = niiwooBillGuaranteeService.listGuaranteeBills(billQueryRequest);
            niiwooBillGuarantees.forEach(v -> result.add(this.transToGuaranteeBillResponseDTO(v)));
        }
        return result;
    }

    /*************************============担保(包含交易后剩余金额信息)==========********************************/
    @Override
    public PageResponseDTO<NiiwooGuaranteeBillReponseDTO> pageGuaranteeBillsWithBalanceAmount(GuaranteeBillQueryRequest billQueryRequest) {
        PageResponseDTO<NiiwooGuaranteeBillReponseDTO> result = pageGuaranteeBills(billQueryRequest);
        List<NiiwooGuaranteeBillReponseDTO> items = null;
        if (result != null && (items = result.getItems()) != null && !items.isEmpty()) {
            items.forEach(v -> {
                BillBase billBase = billBaseService.getOrgBillBaseById(v.getBillBaseId(),null);
                v.setBalanceAmount(billBase == null ? BigDecimal.ZERO : billBase.getBalanceAmount());
            });
        }
        return result;
    }

    /*************************============担保不分页账单(包含交易后剩余金额信息)==========********************************/

    @Override
    public List<NiiwooGuaranteeBillReponseDTO> listGuaranteeBillsWithBalanceAmount(GuaranteeBillQueryRequest billQueryRequest) {
        List<NiiwooGuaranteeBillReponseDTO> result = listGuaranteeBills(billQueryRequest);
        if (!CollectionUtils.isEmpty(result)) {
            result.forEach(v -> {
                BillBase billBase = billBaseService.getOrgBillBaseById(v.getBillBaseId(),null);
                v.setBalanceAmount(billBase == null ? BigDecimal.ZERO : billBase.getBalanceAmount());
            });
        }

        return result;
    }

    /***************************====================用户机构（后台）================*/
    @Override
    public PageResponseDTO<UserBillBackReponseDTO> pageBackstageUserBills(UserBillQueryRequest userBillQueryRequest) {
        PageResponseDTO<UserBillBackReponseDTO> pageResponseDTO = new PageResponseDTO<UserBillBackReponseDTO>();
        Long totalCount = niiwooBillService.countUserNiiwooBills(userBillQueryRequest);
        log.info("totalCount" + totalCount);
        if (totalCount > userBillQueryRequest.getOffset()) {
            List<NiiwooBill> niiwooBills = niiwooBillService.pageNiiwooBills(userBillQueryRequest);

            List<UserBillBackReponseDTO> dtoList = new ArrayList<UserBillBackReponseDTO>();
            //用户的查询余额
            for (NiiwooBill niiwooBill : niiwooBills) {
                UserBillBase billBase = billBaseService.getUserBillBaseById(niiwooBill.getBillBaseId(), niiwooBill.getUserId());
                dtoList.add(this.transToBackUserBillReponseDTO(niiwooBill, billBase));
            }
            pageResponseDTO.setTotalCount(totalCount.intValue());
            pageResponseDTO.setItems(dtoList);
        }

        return pageResponseDTO;


    }

    @Override
    public List<CheckAccountBillDTO> getAccountBillsByRequestNoAndUserId(String requstNo, String userId, Date bizTime) {
        BillBase billBase = billBaseService.getAccountBillBaseByRequestNoAndUserId(requstNo, userId, bizTime);
        if (billBase == null) {
            return null;
        }
        return niiwooBillFacade.getCheckAccountBills(billBase);
    }

    @Override
    public List<CheckAccountBillDTO> getAccountMutilBillsByRequestNoAndUserId(String requstNo, String userId, Date bizTime) {
        List<BillBase> accountBillBaseList = billBaseService.getAccountMultiBillBaseByRequestNoAndUserId(requstNo, userId, bizTime);
        if (accountBillBaseList == null || accountBillBaseList.size() <= 0) {
            return null;
        }
        List<CheckAccountBillDTO> checkAccountBillDTOList = new ArrayList<>();
        for (BillBase billBase : accountBillBaseList) {
            checkAccountBillDTOList.addAll(niiwooBillFacade.getCheckAccountBills(billBase));
        }
        return checkAccountBillDTOList;
    }

    private NiiwooUserBillResponseDTO transToUserBillReponseDTO(NiiwooBill niiwooBill) {
        NiiwooUserBillResponseDTO reponseDTO = new NiiwooUserBillResponseDTO();
        reponseDTO.setBillId(niiwooBill.getBillId());
        reponseDTO.setRelationUserId(niiwooBill.getRelationUserId());
        reponseDTO.setOrderId(niiwooBill.getOrderId());
        reponseDTO.setTitle(niiwooBill.getBillTitle());

        BigDecimal amount = niiwooBill.getAmount();
        if (InoutTypeEnum.OUT_TYPE.getType().equals(niiwooBill.getInoutType())) {
            amount = amount.negate();
        }
        reponseDTO.setAmount(amount);
        reponseDTO.setSecondSubjectCode(niiwooBill.getSecondSortCode());
        reponseDTO.setStatus(niiwooBill.getStatus());
        reponseDTO.setCreateTime(niiwooBill.getCreateTime());
        reponseDTO.setYearMonth(niiwooBill.getYearMonth());
        reponseDTO.setBankCode(niiwooBill.getBankCode());
        reponseDTO.setInOutType(niiwooBill.getInoutType());
        if (StringUtils.isNotEmpty(niiwooBill.getRelationUserId())) {
            UserBasicInfoResponseDTO userBasicInfoResponseDTO = userBasicInfoDubboService.selectUserBaseInfo(niiwooBill.getRelationUserId());
            reponseDTO.setRelationImgSrc(userBasicInfoResponseDTO == null ? "" : userBasicInfoResponseDTO.getHeadImage());
        } else if (Objects.nonNull(niiwooBill.getProjectId())) {
            UserBasicInfoResponseDTO userBasicInfoResponseDTO = userBasicInfoDubboService.selectUserBaseInfo(niiwooBill.getUserId());
            reponseDTO.setRelationImgSrc(userBasicInfoResponseDTO == null ? "" : userBasicInfoResponseDTO.getHeadImage());
        }

        if(Objects.nonNull(niiwooBill.getProjectId()) && Objects.nonNull(niiwooBill.getRelationAccountId()) && niiwooBill.getRelationAccountId() != -1) {
            AccountBase accountBase = accountService.loadAccountById(niiwooBill.getRelationAccountId());
            reponseDTO.setAccountType(accountBase.getAccountType());
        }

        return reponseDTO;
    }

    private NiiwooPlatformBillReponseDTO transToPlatformBillReponseDTO(NiiwooBillPlatform niiwooBill) {
        NiiwooPlatformBillReponseDTO reponseDTO = new NiiwooPlatformBillReponseDTO();
        reponseDTO.setBillId(niiwooBill.getBillId());
        reponseDTO.setAccountId(niiwooBill.getAccountId());
        reponseDTO.setProjectId(niiwooBill.getProjectId());
        reponseDTO.setOrderId(niiwooBill.getOrderId());
        reponseDTO.setAmount(niiwooBill.getAmount());
        reponseDTO.setInoutType(BillSecondSubjectEnum.InoutTypeEnum.getEnumByCode(niiwooBill.getInoutType()));
        reponseDTO.setTitle(niiwooBill.getTitle());
        reponseDTO.setStatus(BillStatusEnum.getEnumByCode(niiwooBill.getStatus()));
        reponseDTO.setFirstSortCode(BillFirstSubjectEnum.getEnumByCode(niiwooBill.getFirstSortCode()));
        reponseDTO.setSecondSortCode(BillSecondSubjectEnum.getEnumByCode(niiwooBill.getSecondSortCode()));
        reponseDTO.setYearMonth(niiwooBill.getYearMonth());
        reponseDTO.setTitle(niiwooBill.getTitle());
        reponseDTO.setRemark(niiwooBill.getRemark());
        reponseDTO.setRelationUserId(niiwooBill.getRelationUserId());
        reponseDTO.setRelationAccountId(niiwooBill.getRelationAccountId());
        reponseDTO.setChannelCode(niiwooBill.getChannelCode());
        if (niiwooBill.getProjectType() != null) {
            reponseDTO.setProjectType(BorrowProjectTypeEnum.enumOf(niiwooBill.getProjectType()));
        }
        reponseDTO.setCreateTime(niiwooBill.getCreateTime());
        reponseDTO.setYearMonth(niiwooBill.getYearMonth());

        return reponseDTO;
    }

    private NiiwooGuaranteeBillReponseDTO transToGuaranteeBillResponseDTO(NiiwooBillGuarantee niiwooBill) {
        NiiwooGuaranteeBillReponseDTO reponseDTO = new NiiwooGuaranteeBillReponseDTO();
        reponseDTO.setBillId(niiwooBill.getBillId());
        reponseDTO.setBillBaseId(niiwooBill.getBillBaseId());
        reponseDTO.setRelationUserId(niiwooBill.getRelationUserId());
        reponseDTO.setRelationAccountId(niiwooBill.getRelationAccountId());
        reponseDTO.setOrderId(niiwooBill.getOrderId());
        reponseDTO.setAmount(niiwooBill.getAmount());
        reponseDTO.setInoutType(InoutTypeEnum.getEnumByCode(niiwooBill.getInoutType()));
        reponseDTO.setFirstSortCode(BillFirstSubjectEnum.getEnumByCode(niiwooBill.getFirstSortCode()));
        reponseDTO.setSecondSortCode(BillSecondSubjectEnum.getEnumByCode(niiwooBill.getSecondSortCode()));
        reponseDTO.setRemark(niiwooBill.getRemark());
        reponseDTO.setStatus(BillStatusEnum.getEnumByCode(niiwooBill.getStatus()));
        reponseDTO.setCreateTime(niiwooBill.getCreateTime());
        reponseDTO.setYearMonth(niiwooBill.getYearMonth());
        if (niiwooBill.getProjectType() != null) {
            reponseDTO.setProjectType(BorrowProjectTypeEnum.enumOf(niiwooBill.getProjectType()));
        }
        reponseDTO.setChannelCode(niiwooBill.getChannelCode());
        reponseDTO.setProjectId(niiwooBill.getProjectId());

        return reponseDTO;
    }

    private UserBillBackReponseDTO transToBackUserBillReponseDTO(NiiwooBill niiwooBill, UserBillBase billBase) {
        UserBillBackReponseDTO reponseDTO = new UserBillBackReponseDTO();
        reponseDTO.setBillId(niiwooBill.getBillId());

        reponseDTO.setRelationUserId(niiwooBill.getRelationUserId());
        reponseDTO.setOrderId(niiwooBill.getOrderId());
        reponseDTO.setAmount(niiwooBill.getAmount());
        reponseDTO.setAccountId(niiwooBill.getAccountId());
        reponseDTO.setCreateTime(niiwooBill.getCreateTime());
        reponseDTO.setFirstSortCode(BillFirstSubjectEnum.getEnumByCode(niiwooBill.getFirstSortCode()));
        reponseDTO.setSecondSortCode(BillSecondSubjectEnum.getEnumByCode(niiwooBill.getSecondSortCode()));

        if(BillSecondSubjectEnum.USER_RECHARGE.getCode().equals(niiwooBill.getSecondSortCode())) {
            reponseDTO.setRemark(niiwooBill.getRemark2());
        }else {
            reponseDTO.setRemark(niiwooBill.getRemark());
        }
        reponseDTO.setRelationAccountId(niiwooBill.getRelationAccountId());
        reponseDTO.setRelationUserId(niiwooBill.getRelationUserId());
        reponseDTO.setInoutType(BillSecondSubjectEnum.InoutTypeEnum.getEnumByCode(niiwooBill.getInoutType()));
        reponseDTO.setUserId(niiwooBill.getUserId());
        reponseDTO.setStatus(niiwooBill.getStatus());
        if(Objects.nonNull(billBase)){
            reponseDTO.setBalanceAmount(billBase.getBalanceAmount());
        }
        if (niiwooBill.getProjectType() != null) {
            reponseDTO.setProjectType(BorrowProjectTypeEnum.enumOf(niiwooBill.getProjectType()));
        }
        reponseDTO.setChannelCode(niiwooBill.getChannelCode());
        reponseDTO.setProjectId(niiwooBill.getProjectId());
        return reponseDTO;
    }

    /**
     * 账单详情表头的数据组装
     *
     * @param niiwooBill
     * @param serialNumber
     * @return
     */
    private PrivacyMasks backupPrivacyMasks = new PrivacyMasks(new PrivacyMaskProperties());

    private BillTitleDTO getDetailTitle(NiiwooBill niiwooBill, String serialNumber) {
        String title = "";
        String titleDown = "";
        BillTitleDTO billTitleDTO = new BillTitleDTO();
        if (niiwooBill.getProjectId() != null) {
            title = ProjectInfoUtil.getLoanUsage(niiwooBill.getProjectTitle());
            titleDown = "项目ID:" + String.valueOf(niiwooBill.getProjectId());
            Integer needJump = 0;
            if (Objects.nonNull(niiwooBill.getProjectType()) && (!BorrowProjectTypeEnum.noJump(niiwooBill.getProjectType()))) {
                if(BorrowProjectTypeEnum.TRANSFER_OF_CREDIT.getValue().equals(niiwooBill.getProjectType())) {
                    //projectType为13跳转到债权详情
                    needJump = 1;
                    billTitleDTO.setJumpType(4);
                    billTitleDTO.setJumpTypeId(String.valueOf(niiwooBill.getProjectId()));
                } else {
                    if (Objects.nonNull(niiwooBill.getInvestId())) {
                        //跳转到投资详情
                        needJump = 1;
                        billTitleDTO.setJumpType(2);
                        billTitleDTO.setJumpTypeId(String.valueOf(niiwooBill.getInvestId()));
                    } else {
                        //借款人本人才能进入借款详情页面
                        ProjectDTO projectDTO = projectDubboService.selectProjectById(niiwooBill.getProjectId());
                        if(Objects.nonNull(projectDTO) && projectDTO.getBorrowUserId().equals(niiwooBill.getUserId())){
                            needJump = 1;
                            billTitleDTO.setJumpType(1);
                            billTitleDTO.setJumpTypeId(String.valueOf(niiwooBill.getProjectId()));
                        }
                    }
                }
            }
            billTitleDTO.setNeedJump(needJump);
        } else {
            if (StringUtils.isNotBlank(niiwooBill.getBankCode())) {
                title = niiwooBill.getBankName();
                String encryptedBankNo;
                try {
                    //system config key decrypt
                    encryptedBankNo = privacyMasks.decryptPrivacy(niiwooBill.getBankAccountNo());
                } catch (DecryptException e) {
                    //new key can not decrypt,try old key(default key)
                    log.warn("AES decrypt exception, try use backup key decrypt", e);
                    encryptedBankNo = backupPrivacyMasks.decryptPrivacy(niiwooBill.getBankAccountNo());
                    log.warn("backup key decrypt success");
                }
                titleDown = "银行卡号:" + privacyMasks.maskBankCard(encryptedBankNo);
            } else {
                title = niiwooBill.getBillTitle();
                titleDown = "交易流水号:" + serialNumber;
            }
            billTitleDTO.setNeedJump(0);
        }

        billTitleDTO.setTitle(title);
        billTitleDTO.setTitleDown(titleDown);

        return billTitleDTO;
    }

    //不再通过时间控制
//    private Boolean jump(Byte projectType,String strDate) {
//        Boolean flag = false;
//        SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
//        try {
//            Date compareDate = format.parse(strDate);
//            flag = new Date().after(compareDate);
//        } catch (ParseException e) {
//            e.printStackTrace();
//        }
//
//        if(!flag && BorrowProjectTypeEnum.ORG_SPEEDLOAN.getValue().equals(projectType)) {
//            flag = false;
//        }else {
//            flag = true;
//        }
//        return flag;
//    }

    private String indexTopTitle(BillQueryRequest billQueryRequest) {
        String topTitle = "";
        MonthBillRequestDTO requestDTO = setMonthBillParamsCondition(billQueryRequest);

        if (Objects.nonNull(billQueryRequest.getIndexBillType())) {
            if (BillFirstSubjectEnum.IndexBillTypeEnum.INDEX_INVEST_BONUS.getIndexCode().equals(billQueryRequest.getIndexBillType().getIndexCode())) {
                requestDTO.setFirstSortCode(null);
                requestDTO.setSecondSortCodes(billQueryRequest.getSecondCodes());
                MonthBillCountResponseDTO responseDTO = niiwooBillService.getMonthBillSum(requestDTO);
                BigDecimal totalAmount = responseDTO == null ? BigDecimal.ZERO : responseDTO.getMonthIncome();
                topTitle = "总计:投资奖励" + totalAmount + "元";
            } else if (BillFirstSubjectEnum.IndexBillTypeEnum.INDEX_RECHARGE.getIndexCode().equals(billQueryRequest.getIndexBillType().getIndexCode())) {
//                requestDTO.setFirstSortCode(BillFirstSubjectEnum.USER_RECHARGE.getCode());
                MonthBillCountResponseDTO responseDTO = niiwooBillService.getMonthBillSum(requestDTO);
                BigDecimal totalAmount = responseDTO == null ? BigDecimal.ZERO : responseDTO.getMonthIncome();
                topTitle = "总计:充值金额" + totalAmount + "元";
            } else if (BillFirstSubjectEnum.IndexBillTypeEnum.INDEX_WITHDRAW.getIndexCode().equals(billQueryRequest.getIndexBillType().getIndexCode())) {
                requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_WITHDRAW.getCode());
                requestDTO.setStatus(BillStatusEnum.SUCCESS.getValue());
                MonthBillCountResponseDTO responseDTO = niiwooBillService.getMonthBillSum(requestDTO);
                BigDecimal totalWithdrawAmount = responseDTO == null ? BigDecimal.ZERO : responseDTO.getMonthIncome();
                requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_WITHDRAW_SERVICE_FEE.getCode());
                MonthBillCountResponseDTO responseFeeDTO = niiwooBillService.getMonthBillSum(requestDTO);
                BigDecimal totalWithdrawFee = responseFeeDTO == null ? BigDecimal.ZERO : responseFeeDTO.getMonthIncome();
                topTitle = "总计:提现金额" + totalWithdrawAmount + "元,手续费" + totalWithdrawFee + "元";
            } else if (BillFirstSubjectEnum.IndexBillTypeEnum.INDEX_INVEST.getIndexCode().equals(billQueryRequest.getIndexBillType().getIndexCode())) {
                requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_INVEST.getCode());
                requestDTO.setStatus(BillStatusEnum.SUCCESS.getValue());
                MonthBillCountResponseDTO responseDTO = niiwooBillService.getMonthBillSum(requestDTO);
                BigDecimal totalAmount = responseDTO == null ? BigDecimal.ZERO : responseDTO.getMonthIncome();
                topTitle = "总计:投资金额" + totalAmount + "元";
            } else if (BillFirstSubjectEnum.IndexBillTypeEnum.INDEX_REPAYMENT.getIndexCode().equals(billQueryRequest.getIndexBillType().getIndexCode())) {
//                requestDTO.setFirstSortCode(BillFirstSubjectEnum.USER_REPAYMENT.getCode());
                MonthBillCountResponseDTO responseDTO = niiwooBillService.getMonthBillSum(requestDTO);
                BigDecimal totalAmount = responseDTO == null ? BigDecimal.ZERO : responseDTO.getMonthIncome();
                topTitle = "总计:还款金额" + totalAmount + "元";
            } else if (BillFirstSubjectEnum.IndexBillTypeEnum.INDEX_INVEST_BACK.getIndexCode().equals(billQueryRequest.getIndexBillType().getIndexCode())) {
                requestDTO.setSecondSortCodes(Arrays.asList(BillSecondSubjectEnum.USER_INVEST_REPAYMENT_CORPUS.getCode(), BillSecondSubjectEnum.USER_INVEST_REPAYMENT_INTEREST.getCode()));
                MonthBillCountResponseDTO responseDTO = niiwooBillService.getMonthBillSum(requestDTO);
                BigDecimal totalAmount = responseDTO == null ? BigDecimal.ZERO : responseDTO.getMonthIncome();

                requestDTO.setSecondSortCodes(null);
                requestDTO.setSecondSortCode(BillSecondSubjectEnum.USER_INVEST_REPAYMENT_PENALTY.getCode());
                MonthBillCountResponseDTO responseOverdueDTO = niiwooBillService.getMonthBillSum(requestDTO);
                BigDecimal totalPrincipalPenalty = responseOverdueDTO == null ? BigDecimal.ZERO : responseOverdueDTO.getMonthIncome();
                topTitle = "总计:投资回款" + totalAmount + "元,罚息" + totalPrincipalPenalty + "元";
            }
        }

        return topTitle;
    }

    private List<UserBillsResponseDTO> listBillResponseDTOs(BillQueryRequest billQueryRequest, List<NiiwooUserBillResponseDTO> dtoList) {
        List<UserBillsResponseDTO> dtos = new ArrayList<>();

        //对账单按月进行分组
        Map<String, List<NiiwooUserBillResponseDTO>> monthBillMap = dtoList.stream().collect(Collectors.groupingBy(NiiwooUserBillResponseDTO::getYearMonth, LinkedHashMap::new, Collectors.toList()));

        MonthBillRequestDTO requestDTO = setMonthBillParamsCondition(billQueryRequest);
        for (Map.Entry<String, List<NiiwooUserBillResponseDTO>> entry : monthBillMap.entrySet()) {
            requestDTO.setYearMonth(entry.getKey());
            requestDTO.setStatus(BillStatusEnum.SUCCESS.getValue());

            BigDecimal monthTotalAmount = null;
            if (Objects.nonNull(billQueryRequest.getIndexBillType()) && BillFirstSubjectEnum.IndexBillTypeEnum.INDEX_INVEST_BONUS.getIndexCode().equals(billQueryRequest.getIndexBillType().getIndexCode())) {
                //汇总投资奖励的月账单总额
                requestDTO.setFirstSortCode(null);
                requestDTO.setSecondSortCodes(billQueryRequest.getSecondCodes());
                MonthBillCountResponseDTO responseDTO = niiwooBillService.getMonthBillSum(requestDTO);
                monthTotalAmount = responseDTO == null ? BigDecimal.ZERO : responseDTO.getMonthIncome();
            } else if (Objects.nonNull(billQueryRequest.getEntranceTypeEnum()) && EntranceTypeEnum.BORROW_INVEST_PLAN_BILL.getCode().equals(billQueryRequest.getEntranceTypeEnum().getCode())) {
                //汇总回款月账单总额
                requestDTO.setInvestId(billQueryRequest.getInvestId());
                requestDTO.setInoutType(InoutTypeEnum.IN_TYPE.getType());
                MonthBillCountResponseDTO monthInSumReponseDTO = niiwooBillService.getMonthBillSum(requestDTO);
                monthTotalAmount = monthInSumReponseDTO == null ? BigDecimal.ZERO : monthInSumReponseDTO.getMonthIncome();
            } else {
                //汇总其它检索类型的月账单总额
                MonthBillCountResponseDTO monthSumReponseDTO = niiwooBillService.getMonthBillSum(requestDTO);
                monthTotalAmount = monthSumReponseDTO == null ? BigDecimal.ZERO : monthSumReponseDTO.getMonthIncome();
            }

            UserBillsResponseDTO responseDTO = new UserBillsResponseDTO();
            responseDTO.setYearMonth(entry.getKey());
            responseDTO.setReponseDTOList(entry.getValue());
            responseDTO.setYearMonthTotalAmount(monthTotalAmount);
            dtos.add(responseDTO);
        }
        return dtos;
    }

    @Override
    public List<String> queryBillDates(BillDatesRequsetDTO billDatesRequsetDTO) {
        return billDateReleatedService.queryBillDates(billDatesRequsetDTO.getReleatedTypeEnum(), billDatesRequsetDTO.getRelatedValue());
    }

    @Override
    public UserAccountAbnormalStatisticsRespDTO findUserAmountByUserId(String userId) {
        Assert.hasLength(userId, "查询用户异常账户统计，用户ID不能为空");
        return niiwooBillService.findUserAmountByUserId(userId);
    }

    @Override
    public BigDecimal statisticalUserBillAmount(String userId, StatisticalUserBillAmountTypeEnum amountType){
        Assert.hasLength(userId, "用户ID不能为空");
        Assert.notNull(amountType, "amountType不能为空");

        return niiwooBillService.statisticalUserBillAmount(userId, amountType);
    }

    @Override
    public MonthBillResponseDTO statisticalUserMonthBill(String userId,String yearMonthBill){
        return niiwooBillService.statisticalUserMonthBill(userId,yearMonthBill);
    }

    //设置参数的公共方法（MonthBillRequestDTO）
    private MonthBillRequestDTO setMonthBillParamsCondition(BillQueryRequest billQueryRequest) {
        MonthBillRequestDTO requestDTO = new MonthBillRequestDTO();
        requestDTO.setUserId(billQueryRequest.getUserId());
        if (billQueryRequest.getIndexBillType() != null) {
            requestDTO.setFirstSortCode(billQueryRequest.getIndexBillType().getIndexCode());
        }

        if (billQueryRequest.getInoutType() != null) {
            requestDTO.setInoutType(billQueryRequest.getInoutType().getType());
        }
        return requestDTO;
    }

    //查询智能投产品包信息
    private ProjectPackageResponseDTO queryProjectPackageInfo(Long packageId){
        ProjectPackageResponseDTO projectPackageResponseDTO = intelligenceInvestDubboService.getIntelligenceInvestInfo(packageId);
        return projectPackageResponseDTO;
    }
}
